package com.code4hire.desktop.converter;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import org.apache.commons.io.FileUtils;

import com.code4hire.desktop.converter.model.Authentication;
import com.code4hire.desktop.converter.model.Profile;
import com.code4hire.desktop.converter.model.ProfileVersion;

public class UI extends JFrame {

    private static final long serialVersionUID = -7185968380340046364L;

    private JMenuBar menubar;

    private JTextField usernameFld;
    private JPasswordField passwordFld;
    private JButton loginButton;

    private JTable fileTable;
    private JProgressBar fileProgress;
    private JProgressBar queueProgress;
    private JButton startStopButton;

    private JProgressBar uploadProgress;
    private JButton uploadButton;

    private List<File> selectedFiles = new ArrayList<File>();

    private Authentication authentication;

    private PropertiesUtil propertiesUtil = new PropertiesUtil();

    public UI() {
        super();
        setSize(500, 400);
        setTitle("Video Convert Tool");
        GridBagLayout gridLayout = new GridBagLayout();
        setLayout(gridLayout);

        JPanel accountPanel = createAccountComponents();
        JPanel createFilesToConvertPanel = createFilesToConvertComponents();
        JPanel createUploadPanel = createUploadComponents();

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;

        constraints.insets = new Insets(5, 5, 5, 5);
        constraints.weightx = 100;
        constraints.gridheight = 1;

        constraints.gridy = 0;
        gridLayout.setConstraints(accountPanel, constraints);
        add(accountPanel);

        constraints.gridy = 1;
        gridLayout.setConstraints(createFilesToConvertPanel, constraints);
        add(createFilesToConvertPanel);

        constraints.gridy = 2;
        gridLayout.setConstraints(createUploadPanel, constraints);
        add(createUploadPanel);

        createMenuBar();

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        try {
            // Set cross-platform Java L&F (also called "Metal")
            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        setVisible(true);
    }

    private void createMenuBar() {
        menubar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic('F');
        JMenu accountMenu = new JMenu("Account");
        accountMenu.setMnemonic('A');

        // file
        JMenuItem open = new JMenuItem("Open file");
        open.setMnemonic('O');
        open.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                final JFileChooser fc = new JFileChooser();

                int returnVal = fc.showOpenDialog(UI.this);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    selectedFiles.add(fc.getSelectedFile());
                    reloadTable();
                }

            }
        });
        fileMenu.add(open);

        JMenuItem close = new JMenuItem("Close");
        close.setMnemonic('C');
        close.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        fileMenu.add(close);

        menubar.add(fileMenu);

        // account

        JMenuItem checkForProfileUpdate = new JMenuItem("Check for profile update");
        checkForProfileUpdate.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                ProfileVersion version = Rest.checkNewVersion();
                if (version == null) {
                    // TODO some error msg
                    System.err.println("connection fail");
                } else {
                    String currentVersion = propertiesUtil.read(PropertiesUtil.VERSION);
                    boolean update = false;
                    if (currentVersion == null) {
                        // save new
                        propertiesUtil.save(PropertiesUtil.VERSION, String.valueOf(version.getVersion()));
                        update = true;
                    } else {
                        try {
                            Integer currentVersionInt = Integer.valueOf(currentVersion);
                            if (currentVersionInt < version.getVersion()) {
                                // update
                                update = true;
                            } else {
                                // TODO message we are up to date
                            }
                        } catch (Exception e1) {
                            propertiesUtil.save(PropertiesUtil.VERSION, String.valueOf(version.getVersion()));
                            update = true;
                        }

                    }
                    if (update) {
                        List<Profile> profiles = Rest.update();
                        for (Profile profile : profiles) {
                            System.out.println(profile);
                        }
                    }
                }
            }
        });
        accountMenu.add(checkForProfileUpdate);

        menubar.add(accountMenu);

        setJMenuBar(menubar);
    }

    private JPanel createAccountComponents() {
        final JPanel accountPanel = new JPanel();

        GridBagLayout gridLayout = new GridBagLayout();
        accountPanel.setLayout(gridLayout);

        usernameFld = new JTextField();
        passwordFld = new JPasswordField();
        loginButton = new JButton("LOGIN");
        Label accountLabel = new Label("Account login:");

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(5, 5, 5, 5);
        constraints.weightx = 100;
        constraints.gridheight = 1;
        constraints.gridx = 0;
        constraints.gridy = 0;
        gridLayout.setConstraints(accountLabel, constraints);
        accountPanel.add(accountLabel);

        constraints.gridx = 1;
        constraints.weightx = 350;
        gridLayout.setConstraints(usernameFld, constraints);
        accountPanel.add(usernameFld);

        constraints.gridx = 2;
        gridLayout.setConstraints(passwordFld, constraints);
        accountPanel.add(passwordFld);

        constraints.gridx = 3;
        constraints.weightx = 100;
        gridLayout.setConstraints(loginButton, constraints);
        accountPanel.add(loginButton);

        loginButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Authentication login = Rest.login(usernameFld.getText(), new String(passwordFld.getPassword()));
                if (login == null) {
                    // TODO some error msg
                    System.err.println("connection fail");
                } else {
                    authentication = login;
                    System.out.println(authentication);
                }
            }
        });

        return accountPanel;
    }

    private JPanel createUploadComponents() {
        final JPanel uploadPanel = new JPanel();
        uploadPanel.setBorder(BorderFactory.createTitledBorder("Upload"));

        GridBagLayout gridLayout = new GridBagLayout();
        uploadPanel.setLayout(gridLayout);

        Label uploadLebel = new Label("Upload");
        uploadProgress = new JProgressBar();
        uploadButton = new JButton("Start");

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(5, 5, 5, 5);
        constraints.weightx = 100;
        constraints.gridheight = 1;
        constraints.gridx = 0;
        constraints.gridy = 0;
        gridLayout.setConstraints(uploadLebel, constraints);

        uploadPanel.add(uploadLebel);

        constraints.gridx = 1;
        constraints.weightx = 200;
        gridLayout.setConstraints(uploadProgress, constraints);
        uploadPanel.add(uploadProgress);

        constraints.gridx = 2;
        constraints.weightx = 100;
        gridLayout.setConstraints(uploadButton, constraints);
        uploadPanel.add(uploadButton);

        return uploadPanel;
    }

    private JPanel createFilesToConvertComponents() {
        final JPanel filesPanel = new JPanel();
        filesPanel.setBorder(BorderFactory.createTitledBorder("Files to convert"));

        GridBagLayout gridLayout = new GridBagLayout();

        filesPanel.setLayout(gridLayout);

        String[] columnNames = { "Name", "Size", "Present" };
        fileTable = new JTable();

        fileTable.setModel(new DefaultTableModel(columnNames, columnNames.length));
        fileTable.setSize(300, 100);

        TableColumn sportColumn = fileTable.getColumnModel().getColumn(2);

        JComboBox comboBox = new JComboBox();
        comboBox.addItem("1080p");
        comboBox.addItem("720p");
        comboBox.addItem("360p");
        comboBox.addItem("240p");
        comboBox.addItem("Keep original");

        sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(5, 5, 5, 5);
        constraints.gridx = 0;
        constraints.gridy = 0;

        constraints.weightx = 1.0;
        constraints.weighty = 1.0;

        JScrollPane scrollPane = new JScrollPane(fileTable);
        fileTable.setPreferredScrollableViewportSize(new Dimension(300, 100));
        fileTable.setRowSelectionAllowed(true);
        fileTable.setColumnSelectionAllowed(false);
        fileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        constraints.gridwidth = 3;

        gridLayout.setConstraints(scrollPane, constraints);
        filesPanel.add(scrollPane);

        constraints.gridwidth = 1;

        fileProgress = new JProgressBar();
        queueProgress = new JProgressBar();

        startStopButton = new JButton("Start/Stop");

        Label fileProgressLabel = new Label("File progress:");
        constraints.gridheight = 1;
        constraints.gridx = 0;
        constraints.gridy = 2;
        gridLayout.setConstraints(fileProgressLabel, constraints);
        filesPanel.add(fileProgressLabel);

        constraints.gridx = 1;
        constraints.weightx = 200;
        gridLayout.setConstraints(fileProgress, constraints);
        filesPanel.add(fileProgress);

        constraints.gridheight = 2;
        constraints.gridx = 2;
        constraints.weightx = 100;
        gridLayout.setConstraints(startStopButton, constraints);
        filesPanel.add(startStopButton);

        Label queueProgressLabel = new Label("Queue progress:");
        constraints.gridheight = 1;
        constraints.gridx = 0;
        constraints.gridy = 3;
        gridLayout.setConstraints(queueProgressLabel, constraints);
        filesPanel.add(queueProgressLabel);

        constraints.gridx = 1;
        constraints.weightx = 200;
        gridLayout.setConstraints(queueProgress, constraints);
        filesPanel.add(queueProgress);

        return filesPanel;
    }

    private void reloadTable() {

        DefaultTableModel dtm = (DefaultTableModel) fileTable.getModel();
        dtm.setRowCount(0);

        for (File file : selectedFiles) {

            dtm.addRow(new Object[] { file.getName(), FileUtils.byteCountToDisplaySize(file.length()), "720p" });
        }
        dtm.fireTableDataChanged();
    }

    public static void main(String[] args) {
        new UI();
    }
}
